home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- #
- # alsa-base control script
- #
- # Description: Used to load and unload ALSA modules and
- # restore and store mixer levels. There is no
- # longer any need to run this script on bootup
- # or shutdown. It ships as /sbin/alsa.
- ### END INIT INFO
-
- set -e
-
- # Exit if alsa-utils package is not installed
- [ -x /sbin/alsactl ] || exit 0
-
- MYNAME=/sbin/alsa
- PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-
- # Default values of variables in /etc/default/alsa
- force_unload_modules_before_suspend=""
-
- [ -f /etc/default/alsa ] && . /etc/default/alsa
-
- # $* MESSAGE
- warn() { echo "${MYNAME}: Warning: $* " >&2 ; }
-
- #
- # Attempt to create /var/run/alsa if it is absent.
- # Return true if /var/run/alsa exists after this attempt,
- # otherwise false.
- #
- check_run_dir()
- {
- [ -d /var/run/alsa ] && return 0
- # We have no business creating /var/run if it doesn't exist
- if ! [ -d /var/run ] ; then
- warn "Could not create /var/run/alsa/ because /var/run/ is not present."
- return 1
- fi
- if ! mkdir --mode=755 /var/run/alsa ; then
- warn "Failed to create /var/run/alsa/."
- return 1
- fi
- [ -d /var/run/alsa ] && return 0
- return 1
- }
-
- echo_procs_using_sound()
- {
- echo $( \
- lsof +D /dev -F rt \
- | awk '/^p/ {pid=$1} /^t/ {type=$1} /^r0x(74|e)..$/ && type == "tCHR" {print pid}' \
- | cut -c 2- \
- | uniq \
- )
- }
-
- # $* [PID]...
- echo_with_command_names()
- {
- [ "$1" ] || return 0
- echo $( \
- ps --no-headers -o "%p %c" "$@" \
- | sed -e 's/\([0-9][0-9]*\) \(.*\)/\1(\2)/' \
- )
- }
-
- kill_procs_using_sound()
- {
- procs_using_sound="$(echo_procs_using_sound)"
- if [ "$procs_using_sound" ] ; then
- echo -n "Terminating processes:"
- for attempt in 1 2 3 4 ; do
- echo -n " ${procs_using_sound}"
- kill $procs_using_sound || :
- sleep 1
- procs_using_sound="$(echo_procs_using_sound)"
- [ "$procs_using_sound" ] || break
- done
- # Either no more procs using sound or attempts ran out
- if [ "$procs_using_sound" ] ; then
- echo -n " (with SIGKILL:) ${procs_using_sound}"
- kill -9 $procs_using_sound || :
- sleep 1
- fi
- procs_using_sound="$(echo_procs_using_sound)"
- if [ "$procs_using_sound" ] ; then
- echo " (failed: processes still using sound devices: $(echo_with_command_names $procs_using_sound))."
- return 1
- fi
- echo "."
- fi
- return 0
- }
-
- # $* MODULE-NAME [MODULE-NAME]... | "all"
- unload_modules()
- {
- procs_using_sound="$(echo_procs_using_sound)"
- if [ "$procs_using_sound" ] ; then
- warn "Processes using sound devices: $(echo_with_command_names $procs_using_sound)."
- fi
- if check_run_dir ; then
- :> /var/run/alsa/modules-removed
- else
- warn "Not keeping list of removed modules because /var/run/alsa is absent.
- It will not be possible automatically to reload these modules."
- fi
- echo -n "Unloading ALSA sound driver modules:"
- [ -d /proc/asound ] || { echo " (none loaded)." ; return 0 ; }
- echo_snd_modules_loaded()
- {
- lsmod \
- | sed -n -e 's/^\(snd[-_][^[:space:]]*\)[[:space:]].*/\1/p' \
- | sed -e 's/_/-/g'
- }
- for FSMBS in $* ; do
- MODULES_TO_REMOVE=""
- SND_MODULES_LOADED="$(echo_snd_modules_loaded)"
- case "$FSMBS" in
- all)
- MODULES_TO_REMOVE="$SND_MODULES_LOADED"
- ;;
- snd_*|snd-*)
- FSMBS="$(echo "$FSMBS" | sed -e 's/_/-/g')"
- for M in $SND_MODULES_LOADED ; do
- if [ "$FSMBS" = "$M" ] ; then
- MODULES_TO_REMOVE="$FSMBS"
- break
- fi
- done
- ;;
- esac
- [ "$MODULES_TO_REMOVE" ] || continue
- echo "$MODULES_TO_REMOVE" >> /var/run/alsa/modules-removed
- for M in $MODULES_TO_REMOVE ; do
- echo -n " ${M}"
- modprobe -r "$M" >/dev/null 2>&1 || :
- done
- done
- if [ -f /var/run/alsa/modules-removed ] ; then
- MODULES_STILL_LOADED="$(echo_snd_modules_loaded | grep -F -f /var/run/alsa/modules-removed)"
- MODULES_STILL_LOADED="$(echo $MODULES_STILL_LOADED)"
- else
- MODULES_STILL_LOADED=""
- fi
- if [ "$MODULES_STILL_LOADED" ] ; then
- echo " (failed: modules still loaded: ${MODULES_STILL_LOADED})."
- return 1
- else
- echo "."
- return 0
- fi
- }
-
- # $* MODULE-NAME [MODULE-NAME]... | "all"
- force_unload_modules()
- {
- kill_procs_using_sound || :
- unload_modules "$@" || return 1
- return 0
- }
-
- load_unloaded_modules()
- {
- LUM_RETURNSTATUS=0
- MODULES_TO_LOAD=""
- [ -d /var/run/alsa ] || mkdir -p /var/run/alsa
- echo -n "Loading ALSA sound driver modules:"
- [ -f /var/run/alsa/modules-removed ] && MODULES_TO_LOAD="$(echo $(cat /var/run/alsa/modules-removed))"
- [ "$MODULES_TO_LOAD" ] || { echo " (none to reload)." ; return $LUM_RETURNSTATUS ; }
- echo -n " $MODULES_TO_LOAD"
- for MDL in $MODULES_TO_LOAD ; do
- modprobe $MDL || LUM_RETURNSTATUS=1
- done
- case "$LUM_RETURNSTATUS" in
- 0) echo "." ;;
- *) echo " (failed)." ;;
- esac
- return $LUM_RETURNSTATUS
- }
-
- case "$1" in
- unload)
- unload_modules all || exit $?
- ;;
- reload)
- EXITSTATUS=0
- unload_modules all || EXITSTATUS=1
- load_unloaded_modules || EXITSTATUS=1
- exit $EXITSTATUS
- ;;
- force-unload)
- force_unload_modules all || exit $?
- ;;
- force-reload)
- EXITSTATUS=0
- force_unload_modules all || EXITSTATUS=1
- load_unloaded_modules || EXITSTATUS=1
- exit $EXITSTATUS
- ;;
- suspend)
- case "$force_unload_modules_before_suspend" in
- ""|false) : ;;
- all|true) /sbin/alsactl store && force_unload_modules all || exit $? ;;
- *) /sbin/alsactl store && force_unload_modules $force_unload_modules_before_suspend || exit $? ;;
- esac
- ;;
- resume)
- case "$force_unload_modules_before_suspend" in
- ""|false) : ;;
- *) load_unloaded_modules && /sbin/alsactl restore || exit $? ;;
- esac
- ;;
- *)
- echo "Usage: $MYNAME {unload|reload|force-unload|force-reload|suspend|resume}" >&2
- exit 3
- ;;
- esac
-